package org.lzy.shop.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import androidx.core.content.ContextCompat
import org.lzy.shop.R

/**
 * 自定义滚轮选择器
 */
class WheelView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    // 数据列表
    private var dataList: List<String> = emptyList()
    // 选中的位置
    private var selectedPosition: Int = 0
    // 每一项的高度
    private var itemHeight: Int = 80
    // 文字大小
    private var textSize: Float =36f
    // 文字颜色
    private var normalTextColor: Int = ContextCompat.getColor(context, R.color.blue_a2adff)
    private var selectedTextColor: Int = ContextCompat.getColor(context, R.color.colorPrimary)
    // 背景色
    private var backgroundColor: Int = ContextCompat.getColor(context, R.color.windowBackground)
    // 分割线颜色
    private var dividerColor: Int = ContextCompat.getColor(context, R.color.OutlineVariant)
    // 绘制相关
    private val paint: Paint = Paint(Paint.ANTI_ALIAS_FLAG)
    private val centerLinePaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG)
    // 滚动相关
    private var scrollOffset: Float = 0f
    private var lastY: Float = 0f
    private var velocityY: Float = 0f
    private var isScrolling: Boolean = false
    private val touchSlop: Int = ViewConfiguration.get(context).scaledTouchSlop
    // 选中监听器
    private var onItemSelectedListener: ((position: Int, item: String) -> Unit)? = null

    init {
        // 初始化画笔
        paint.textSize = textSize
        paint.textAlign = Paint.Align.CENTER

        centerLinePaint.strokeWidth = 2f
        centerLinePaint.color = dividerColor
    }

    /**
     * 设置数据列表
     */
    fun setDataList(list: List<String>) {
        dataList = list
        if (list.isNotEmpty()) {
            selectedPosition = 0
            scrollOffset = 0f
        }
        invalidate()
    }

    /**
     * 设置选中位置
     */
    fun setSelectedPosition(position: Int) {
        if (position in dataList.indices) {
            selectedPosition = position
            scrollOffset = 0f
            invalidate()
            notifyItemSelected()
        }
    }

    /**
     * 获取选中的位置
     */
    fun getSelectedPosition(): Int {
        return selectedPosition
    }

    /**
     * 获取选中的项
     */
    fun getSelectedItem(): String? {
        return if (dataList.isNotEmpty() && selectedPosition in dataList.indices) {
            dataList[selectedPosition]
        } else null
    }

    /**
     * 设置选中监听器
     */
    fun setOnItemSelectedListener(listener: ((position: Int, item: String) -> Unit)?) {
        onItemSelectedListener = listener
    }

    /**
     * 通知选中项变化
     */
    private fun notifyItemSelected() {
        if (dataList.isNotEmpty() && selectedPosition in dataList.indices) {
            onItemSelectedListener?.invoke(selectedPosition, dataList[selectedPosition])
        }
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val height = itemHeight * 7 // 默认显示7个选项
        setMeasuredDimension(
            MeasureSpec.getSize(widthMeasureSpec),
            height
        )
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        // 绘制背景
        canvas.drawColor(backgroundColor)

        // 绘制中间选中区域的分割线
        val centerY = height / 2f
        canvas.drawLine(0f, centerY - itemHeight / 2, width.toFloat(), centerY - itemHeight / 2, centerLinePaint)
        canvas.drawLine(0f, centerY + itemHeight / 2, width.toFloat(), centerY + itemHeight / 2, centerLinePaint)

        if (dataList.isEmpty()) return

        // 计算显示的范围
        val startIndex = Math.max(0, (selectedPosition - 3))
        val endIndex = Math.min(dataList.size - 1, (selectedPosition + 3))

        // 绘制每个选项
        for (i in startIndex..endIndex) {
            val pos = i
            val y = centerY + (pos - selectedPosition) * itemHeight + scrollOffset

            // 计算透明度和缩放比例
            val distance = Math.abs(y - centerY)
            val ratio = 1f - Math.min(1f, distance / (itemHeight * 2))

            // 设置文字颜色和透明度
            if (Math.abs(y - centerY) < itemHeight / 2) {
                // 选中项
                paint.color = selectedTextColor
                paint.alpha = 255
            } else {
                // 非选中项
                paint.color = normalTextColor
                paint.alpha = (255 * ratio).toInt()
            }

            // 绘制文字
            val text = dataList[pos]
            val textY = y + (paint.descent() - paint.ascent()) / 2 - paint.descent()
            canvas.drawText(text, width / 2f, textY, paint)
        }
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                lastY = event.y
                velocityY = 0f
                isScrolling = true
                return true
            }

            MotionEvent.ACTION_MOVE -> {
                val deltaY = event.y - lastY
                lastY = event.y
                velocityY = deltaY

                // 更新偏移量
                scrollOffset += deltaY

                // 处理滚动到边界的情况
                if (scrollOffset > itemHeight / 2 && selectedPosition > 0) {
                    selectedPosition--
                    scrollOffset -= itemHeight
                    notifyItemSelected()
                } else if (scrollOffset < -itemHeight / 2 && selectedPosition < dataList.size - 1) {
                    selectedPosition++
                    scrollOffset += itemHeight
                    notifyItemSelected()
                }

                invalidate()
                return true
            }

            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                isScrolling = false

                // 根据惯性调整位置
                if (Math.abs(velocityY) > touchSlop * 2) {
                    if (velocityY > 0 && selectedPosition <dataList.size-1) {
                        // 向上滚动
                        selectedPosition++
                        notifyItemSelected()
                    } else if (velocityY < 0 && selectedPosition >0) {
                        // 向下滚动
                        selectedPosition--
                        notifyItemSelected()
                    }
                }

                // 回到中间位置
                scrollOffset = 0f
                invalidate()
                return true
            }
        }
        return super.onTouchEvent(event)
    }
}